package com.liquidcode.cellular;


import collisionPrimitives.CRect;
import attack.behaviors.CDynamicBullet;
import attack.behaviors.CStaticBullet;
import entities.CEnemy;
import entities.CPlayer;

public class CCollisionManager {
	private static CCollisionManager mInstance;
	private int PUSH_AMOUNT = 2;

	public CCollisionManager() {

	}

	public static CCollisionManager getInstance() {
		if (mInstance == null)
			mInstance = new CCollisionManager();

		return mInstance;
	}
	
	private boolean PointInRect(float x, float y, CRect r)
	{
		if( x > r.min.getX() && x < r.max.getX() &&
			y > r.min.getY() && y < r.max.getY() )
		{
			return true;
		}
		
		return false;
	}
	
	private boolean RectToRect(CEnemy a, CEnemy b)
	{
		if( a == b )
			return false;
		
		CRect aRect = a.getCollisionRect();
		CRect bRect = b.getCollisionRect();
		
		// check which side it was 
		if( aRect.min.getX() <= bRect.max.getX() && aRect.min.getX() >= bRect.min.getX() &&
				(aRect.max.getY() >= bRect.min.getY() && aRect.max.getY() <= bRect.max.getY() ||
						aRect.min.getY() <= bRect.max.getY() && aRect.min.getY() >= bRect.min.getY())) /* Left */ 
		{
			a.setPosX(a.getPosX() + PUSH_AMOUNT);
			return true;
		}
		if( aRect.max.getX() >= bRect.min.getX() && aRect.max.getX() <= bRect.max.getX() ) /* Right */ 
		{
			a.setPosX(a.getPosX() - PUSH_AMOUNT);
			return true;
		}
		if( aRect.max.getY() >= bRect.min.getY() && aRect.max.getY() <= bRect.max.getY() &&
				(aRect.min.getX() <= bRect.max.getX() && aRect.min.getX() >= bRect.min.getX() || 
						aRect.max.getX() >= bRect.min.getX() && aRect.max.getX() <= bRect.max.getX())) /* Top) */ 
		{
			a.setPosY(a.getPosY() + PUSH_AMOUNT);
			return true;
		}
		if( aRect.min.getY() <= bRect.max.getY() && aRect.min.getY() >= bRect.min.getY() &&
				(aRect.min.getX() <= bRect.max.getX() && aRect.min.getX() >= bRect.min.getX() || 
				aRect.max.getX() >= bRect.min.getX() && aRect.max.getX() <= bRect.max.getX())) /* Bottom */ 
		{
			a.setPosY(a.getPosY() - PUSH_AMOUNT);
			return true;
		}
		return false;
	}
	
	private boolean CheckBulletCollision(float dt)
	{
		synchronized(CBulletManager.getInstance().getStaticList())
		{
			for( CStaticBullet bullet : CBulletManager.getInstance().getStaticList() )
			{
				if( bullet.getAlive() == true )
				{
					synchronized(CEnemyManager.getInstance().getEnemyList())
					{
						for( CEnemy enemy : CEnemyManager.getInstance().getEnemyList() )
						{
							if( bullet.getOwner() == null )
								continue;
							if( enemy.getAlive() == true && bullet.getOwner().TAG != "enemy" )
							{
								if( PointInRect(bullet.getPosX(), bullet.getPosY(), enemy.getCollisionRect()) == true && bullet.getOwner() != enemy )
								{
									if( bullet.isDestroyOnHit() == true ) {										
										bullet.setAlive(false);
									}
									enemy.getHealthBar().DecreaseHealth(bullet.getDamage());
									if( bullet.isCollidable() == true ) {
										enemy.PushBack(bullet.getVelocity());										
									}
								}
							}
						}
					}	
				}
			}
		}
		
//		for( CDynamicBullet obj : CBulletManager.getInstance().getDynamicList() )
//		{
//		
//		}
		
		return false;
	}
	
	private boolean CheckBulletPlayerCollision(float dt)
	{
		synchronized(CBulletManager.getInstance().getStaticList())
		{
			for( CStaticBullet bullet : CBulletManager.getInstance().getStaticList() )
			{
				if( bullet.getAlive() == true )
				{
					synchronized(CPlayer.getInstance())
					{
							if( CPlayer.getInstance().getAlive() == true )
							{
								if( PointInRect(bullet.getPosX(), bullet.getPosY(), CPlayer.getInstance().getCollisionRect()) == true && bullet.getOwner() != CPlayer.getInstance() )
								{
									bullet.setAlive(false);
									if( CPlayer.getInstance().getShield().isDraining() == false ) {
										CPlayer.getInstance().getHealthBar().DecreaseHealth(bullet.getDamage());
									}
									return true;
								}
							}
						
					}	
				}
			}
		}
		
		return false;
	}
	
	private boolean CheckTouchCollisions(float dt)
	{
		synchronized(CEnemyManager.getInstance().getEnemyList())
		{
			int listSize = CEnemyManager.getInstance().getEnemyList().size();
			for( int i = 0; i < listSize; ++i )
			{
				CEnemy a = CEnemyManager.getInstance().getEnemyList().get(i);
				if( a.getAlive() == false )
					continue;
				for( int other = 1; other < listSize; ++other )
				{
					CEnemy b = CEnemyManager.getInstance().getEnemyList().get(other);
					if(b.getAlive() == false)
						continue;
					
					RectToRect(a, b);
				}
			}
		}
		
		
		return false;
	}
	
	public void UpdateCollisions(float dt)
	{
		CheckBulletCollision(dt);
		CheckBulletPlayerCollision(dt);
		CheckTouchCollisions(dt);
	}

	
}
